﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;

namespace ImageOfStock
{
    /// <summary>
    /// 公共类
    /// </summary>
    public class CommonClass
    {
        /// <summary>
        /// 获取Guid
        /// </summary>
        /// <returns></returns>
        public static string GetGuid()
        {
            return System.Guid.NewGuid().ToString();
        }

        /// <summary>
        /// 获取指定索引的移动平均值
        /// </summary>
        /// <param name="r"></param>
        /// <param name="field"></param>
        /// <param name="target"></param>
        /// <param name="curValue"></param>
        /// <returns></returns>
        public static double CalcuteSimpleMovingAvg(int r, int cycle, string field, string target, double curValue, DataTable dataSource)
        {
            double sumValue = 0;
            if (r == cycle - 1)
            {
                for (int i = 0; i <= r - 1; i++)
                {
                    sumValue += Convert.ToDouble(dataSource.Rows[i][target]);
                }
                sumValue += curValue;
                return sumValue / cycle;
            }
            else if (r > cycle - 1)
            {
                sumValue = Convert.ToDouble(dataSource.Rows[r - 1][field]) * cycle;
                sumValue -= Convert.ToDouble(dataSource.Rows[r - cycle][target]);
                sumValue += curValue;
                return sumValue / cycle;
            }
            else
            {
                return double.MinValue;
            }
        }

        /// <summary>
        /// 获取指定索引的指数移动平均值
        /// </summary>
        /// <param name="field"></param>
        /// <param name="target"></param>
        /// <param name="cycle"></param>
        /// <param name="dataSource"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static double CalculateExponentialMovingAvg(string field, string target, int cycle, DataTable dataSource, int r)
        {
            DataRow dr = dataSource.Rows[r];
            double closeValue = Convert.ToDouble(dr[target]);
            double lastEMA = 0;
            double newEmaValue = 0;
            if (r > 0)
            {
                lastEMA = Convert.ToDouble(dataSource.Rows[r - 1][field]);
                newEmaValue = (closeValue * 2 + lastEMA * (cycle - 1)) / (cycle + 1);
            }
            return newEmaValue;
        }

        /// <summary>
        /// 获取最新的面板的ID
        /// </summary>
        private static int panelID = 0;

        public static int GetPanelID()
        {
            return panelID++;
        }

        /// <summary>
        /// 根据DateTime获取Timekey
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetTimeKey(DateTime dt)
        {
            string month = dt.Month.ToString().Length == 1 ? "0" + dt.Month.ToString() : dt.Month.ToString();
            string day = dt.Day.ToString().Length == 1 ? "0" + dt.Day.ToString() : dt.Day.ToString();
            string hour = dt.Hour.ToString().Length == 1 ? "0" + dt.Hour.ToString() : dt.Hour.ToString();
            string minute = dt.Minute.ToString().Length == 1 ? "0" + dt.Minute.ToString() : dt.Minute.ToString();
            string second = dt.Second.ToString().Length == 1 ? "0" + dt.Second.ToString() : dt.Second.ToString();
            return dt.Year + month + day + hour + minute + second;
        }

        /// <summary>
        /// 根据timeKey获取datetime
        /// </summary>
        /// <param name="timeKey"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeByTimeKey(string timeKey)
        {
            int year = timeKey.Length >= 4 ? Convert.ToInt32(timeKey.Substring(0, 4)) : 1970;
            int month = timeKey.Length >= 6 ? Convert.ToInt32(timeKey.Substring(4, 2)) : 1;
            int day = timeKey.Length >= 8 ? Convert.ToInt32(timeKey.Substring(6, 2)) : 1;
            int hr = timeKey.Length >= 10 ? Convert.ToInt32(timeKey.Substring(8, 2)) : 0;
            int mn = timeKey.Length >= 12 ? Convert.ToInt32(timeKey.Substring(10, 2)) : 0;
            int sc = timeKey.Length >= 14 ? Convert.ToInt32(timeKey.Substring(12, 2)) : 0;
            DateTime dt = new DateTime(year, month, day, hr, mn, sc);
            return dt;
        }

        /// <summary>
        /// 根据日期类型和时间获取经过处理后的TimeKey
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetCalenderFormatTimeKey(string value, IntervalType interval)
        {
            string timeKey = string.Empty;
            switch (interval)
            {
                case IntervalType.Year:
                    timeKey = value.Substring(0, 4);
                    break;
                case IntervalType.Month:
                    timeKey = value.Substring(0, 4) + "/" + value.Substring(4, 2);
                    break;
                case IntervalType.Week:
                case IntervalType.Day:
                    timeKey = value.Substring(0, 4) + "/" + value.Substring(4, 2) + "/" + value.Substring(6, 2);
                    break;
                case IntervalType.Minute:
                    timeKey = value.Substring(8, 2) + ":" + value.Substring(10, 2);
                    break;
                case IntervalType.Second:
                    timeKey = value.Substring(8, 2) + ":" + value.Substring(10, 2) + ":" + value.Substring(12, 2);
                    break;
            }
            return timeKey;
        }

        /// <summary>
        /// 返回一组数据的最小值
        /// </summary>
        /// <param name="valueList"></param>
        /// <returns></returns>
        public static double GetLowValue(List<double> valueList)
        {
            double low = 0;
            for (int i = 0; i < valueList.Count; i++)
            {
                if (i == 0)
                {
                    low = valueList[i];
                }
                else
                {
                    if (low > valueList[i])
                    {
                        low = valueList[i];
                    }
                }
            }
            return low;
        }

        /// <summary>
        /// 返回一组数组的最大值
        /// </summary>
        /// <param name="valueList"></param>
        /// <returns></returns>
        public static double GetHighValue(List<double> valueList)
        {
            double high = 0;
            for (int i = 0; i < valueList.Count; i++)
            {
                if (i == 0)
                {
                    high = valueList[i];
                }
                else
                {
                    if (high < valueList[i])
                    {
                        high = valueList[i];
                    }
                }
            }
            return high;
        }

        /// <summary>
        /// 获取一个表中的数据的最小值的记录号
        /// </summary>
        /// <param name="dicValues"></param>
        /// <returns></returns>
        public static int GetLoweRecord(List<object[]> dicValues)
        {
            double low = 0;
            int index = -1;
            for (int i = 0; i < dicValues.Count; i++)
            {
                int j = Convert.ToInt32(dicValues[i][0]);
                double value = Convert.ToDouble(dicValues[i][1]);
                if (i == 0)
                {
                    index = j;
                    low = value;
                }
                else
                {
                    if (low > value)
                    {
                        index = j;
                        low = value;
                    }
                }
            }
            return index;
        }

        /// <summary>
        /// 获取一个表中的数据的最大值的记录号
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static int GetHighRecord(List<object[]> dicValues)
        {
            double high = 0;
            int index = -1;
            for (int i = 0; i < dicValues.Count; i++)
            {
                int j = Convert.ToInt32(dicValues[i][0]);
                double value = Convert.ToDouble(dicValues[i][1]);
                if (i == 0)
                {
                    index = j;
                    high = value;
                }
                else
                {
                    if (high < value)
                    {
                        high = value;
                        index = j;
                    }
                }
            }
            return index;
        }

        /// <summary>
        /// 根据保留小数的位置将double型转化为string型
        /// </summary>
        /// <param name="value"></param>
        /// <param name="digit"></param>
        /// <returns></returns>
        public static string GetValueByDigit(double value, int digit)
        {
            if (digit > 0)
            {
                StringBuilder sbFormat = new StringBuilder();
                string strValue = value.ToString();
                if (strValue.IndexOf(".") != -1)
                {
                    sbFormat.Append(strValue.Substring(0, strValue.IndexOf(".") + 1));
                    for (int i = 0; i < digit; i++)
                    {
                        int pos = strValue.IndexOf(".") + (i + 1);
                        if (pos <= strValue.Length - 1)
                        {
                            sbFormat.Append(strValue.Substring(pos, 1));
                        }
                        else
                        {
                            sbFormat.Append("0");
                        }
                    }
                }
                else
                {
                    sbFormat.Append(strValue + ".");
                    for (int i = 0; i < digit; i++)
                    {
                        sbFormat.Append("0");
                    }
                }
                return sbFormat.ToString();
            }
            return value.ToString();
        }

        /// <summary>
        /// 获取一个带圆弧角的矩形
        /// </summary>
        /// <param name="cornerRadius"></param>
        /// <param name="rect"></param>
        /// <returns></returns>
        public static GraphicsPath GetRoundRectangle(int cornerRadius, RectangleF rect)
        {
            GraphicsPath roundedRect = new GraphicsPath();
            roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
            roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
            roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
            roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);
            roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
            roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);
            roundedRect.CloseFigure();
            return roundedRect;
        }

        /// <summary>
        /// 计算坐标轴的函数
        /// </summary>
        /// <param name="XMin"></param>
        /// <param name="XMax"></param>
        /// <param name="N"></param>
        /// <param name="SMin"></param>
        /// <param name="Step"></param>
        /// <returns></returns>
        public static int GridScale(double XMin, double XMax, int N, ref double SMin, ref double Step, double m_fTick)
        {
            int iNegScl;
            int iNm1;
            double lfIniStep;
            double lfSclStep;
            double lfTmp;
            double lfSMax;
            int it;
            int i;
            int[] Steps = { 10, 12, 15, 16, 20, 25, 30, 40, 50, 60, 75, 80, 100, 120, 150 };
            int iNS = Steps.Length;
            if (XMin > XMax)
            {
                lfTmp = XMin;
                XMin = XMax;
                XMax = lfTmp;
            }
            if (XMin == XMax)
                XMax = XMin == 0.0 ? 1.0 : XMin + Math.Abs(XMin) / 10.0;
            if (XMax <= 0)
            {
                iNegScl = 1;
                lfTmp = XMin;
                XMin = -XMax;
                XMax = -lfTmp;
            }
            else
                iNegScl = 0;
            if (N < 2)
                N = 2;
            iNm1 = N - 1;
            for (it = 0; it < 3; it++)
            {
                lfIniStep = (XMax - XMin) / iNm1;
                lfSclStep = lfIniStep;

                int pow10 = 0;

                for (; lfSclStep < 10.0; lfSclStep *= 10.0) pow10--;
                for (; lfSclStep > 100.0; lfSclStep /= 10.0) pow10++;
                for (i = 0; i < iNS && lfSclStep > Steps[i]; i++) ;
                do
                {
                    Step = Steps[i] * Math.Pow(10, (double)pow10);

                    if (m_fTick != 0.0)
                    {
                        Step = Math.Floor(Step / m_fTick) * m_fTick;
                    }

                    SMin = Math.Floor(XMin / Step) * Step;
                    lfSMax = SMin + iNm1 * Step;
                    if (XMax <= lfSMax)
                    {
                        if (iNegScl == 1)
                            SMin = -lfSMax;
                        Step *= iNm1 / (N - 1);
                        return 1;
                    }
                    i++;
                }
                while (i < iNS);
                iNm1 *= 2;
            }
            return 0;
        }
    }

    /// <summary>
    /// 面板属性设置
    /// </summary>
    public class ChartPanel
    {
        public ChartPanel()
        {
            infoBombField = CommonClass.GetGuid();
            panelBorder_Pen.DashStyle = DashStyle.Dash;
            grid_Pen.DashStyle = DashStyle.Dash;
        }

        ~ChartPanel()
        {
            if (bgBrush != null) { bgBrush.Dispose(); }
            if (xtip_Brush != null) { xtip_Brush.Dispose(); }
            if (xTipFont_Brush != null) { xTipFont_Brush.Dispose(); }
            if (xTipFont_Pen != null) { xTipFont_Pen.Dispose(); }
            if (leftyTip_Brush != null) { leftyTip_Brush.Dispose(); }
            if (leftyTipFont_Brush != null) { leftyTipFont_Brush.Dispose(); }
            if (leftTipFont_Pen != null) { leftTipFont_Pen.Dispose(); }
            if (rightyTip_Brush != null) { rightyTip_Brush.Dispose(); }
            if (rightyTipFont_Brush != null) { rightyTipFont_Brush.Dispose(); }
            if (panelBorder_Pen != null) { panelBorder_Pen.Dispose(); }
            if (titleFont_Brush != null) { titleFont_Brush.Dispose(); }
            if (grid_Pen != null) { grid_Pen.Dispose(); }
            if (coordinateXFont_Brush != null) { coordinateXFont_Brush.Dispose(); }
            if (leftYFont_Brush != null) { leftYFont_Brush.Dispose(); }
            if (rightYFont_Brush != null) { rightYFont_Brush.Dispose(); }
            if (rightyTipFont_Pen != null) { rightyTipFont_Pen.Dispose(); }
            if (xScalePen != null) { xScalePen.Dispose(); }
            if (leftScalePen != null) { leftScalePen.Dispose(); }
            if (rightScalePen != null) { rightScalePen.Dispose(); }
            if (crossHair_Pen != null) { crossHair_Pen.Dispose(); }
        }

        /// <summary>
        /// 十字线的画笔
        /// </summary>
        private Pen crossHair_Pen = new Pen(Color.White);

        public Pen CrossHair_Pen
        {
            get { return crossHair_Pen; }
            set { crossHair_Pen = value; }
        }

        /// <summary>
        /// 网格线的幅度
        /// </summary>
        private int gridInterval = 3;

        public int GridInterval
        {
            get { return gridInterval; }
            set { gridInterval = value; }
        }

        /// <summary>
        /// 信息地雷的字段
        /// </summary>
        private string infoBombField = string.Empty;

        public string InfoBombField
        {
            get { return infoBombField; }
            set { infoBombField = value; }
        }

        /// <summary>
        /// 信息地雷的颜色
        /// </summary>
        private Color infoBombColor = Color.White;

        public Color InfoBombColor
        {
            get { return infoBombColor; }
            set { infoBombColor = value; }
        }

        /// <summary>
        /// 信息地雷的选中色
        /// </summary>
        private Color infoBombSelectedColor = Color.FromArgb(255, 255, 153);

        public Color InfoBombSelectedColor
        {
            get { return infoBombSelectedColor; }
            set { infoBombSelectedColor = value; }
        }

        /// <summary>
        /// 信息地雷提示框的背景色
        /// </summary>
        private Color infoBombTipColor = Color.FromArgb(255, 255, 153);

        public Color InfoBombTipColor
        {
            get { return infoBombTipColor; }
            set { infoBombTipColor = value; }
        }

        /// <summary>
        /// 信息地雷提示框的文字颜色
        /// </summary>
        private Color infoBombTipTextColor = Color.Black;

        public Color InfoBombTipTextColor
        {
            get { return infoBombTipTextColor; }
            set { infoBombTipTextColor = value; }
        }

        /// <summary>
        /// 保存标记的集合
        /// </summary>
        private Dictionary<string, List<SignalSeries>> signalSeriesDic = new Dictionary<string, List<SignalSeries>>();

        public Dictionary<string, List<SignalSeries>> SignalSeriesDic
        {
            get { return signalSeriesDic; }
            set { signalSeriesDic = value; }
        }

        /// <summary>
        /// 绘制标题的集合
        /// </summary>
        private List<TitleField> titleFieldList = new List<TitleField>();

        public List<TitleField> TitleFieldList
        {
            get { return titleFieldList; }
            set { titleFieldList = value; }
        }

        /// <summary>
        /// 用户自定义标题
        /// </summary>
        private bool userDefinedTitle = false;

        public bool UserDefinedTitle
        {
            get { return userDefinedTitle; }
            set { userDefinedTitle = value; }
        }

        /// <summary>
        /// 面板显示数值保留小数的位数
        /// </summary>
        private int digit = 2;

        public int Digit
        {
            get { return digit; }
            set { digit = value; }
        }

        /// <summary>
        /// 面板的ID
        /// </summary>
        private int panelID;

        public int PanelID
        {
            get { return panelID; }
            set { panelID = value; }
        }

        private int verticalPercent = 0;
        /// <summary>
        /// 纵向比例
        /// </summary>
        public int VerticalPercent
        {
            get { return verticalPercent; }
            set { verticalPercent = value; }
        }

        /// <summary>
        /// Y轴的Tick
        /// </summary>
        private double yScaleTick = 0.01;

        public double YScaleTick
        {
            get { return yScaleTick; }
            set { yScaleTick = value; }
        }

        /// <summary>
        /// 卖点对应的字段
        /// </summary>
        private string sellSignalField = string.Empty;

        [Browsable(false)]
        public string SellSignalField
        {
            get { return sellSignalField; }
            set { sellSignalField = value; }
        }

        /// <summary>
        /// 面板的标题
        /// </summary>
        private string panelTitle = string.Empty;

        public string PanelTitle
        {
            get { return panelTitle; }
            set { panelTitle = value; }
        }

        /// <summary>
        /// 是否显示网格线
        /// </summary>
        private bool showGrid = true;

        public bool ShowGrid
        {
            get { return showGrid; }
            set { showGrid = value; }
        }

        /// <summary>
        /// 最大值
        /// </summary>
        private double maxValue;

        [Browsable(false)]
        public double MaxValue
        {
            get { return maxValue; }
            set { maxValue = value; }
        }

        /// <summary>
        /// 最小值
        /// </summary>
        private double minValue;

        [Browsable(false)]
        public double MinValue
        {
            get { return minValue; }
            set { minValue = value; }
        }

        /// <summary>
        /// 当前显示的线条的日期类型
        /// </summary>
        private IntervalType interval = IntervalType.Day;

        [Browsable(true)]
        public IntervalType Interval
        {
            get { return interval; }
            set { interval = value; }
        }

        /// <summary>
        /// 面板的矩形
        /// </summary>
        private Rectangle rectPanel = new Rectangle();

        public Rectangle Bounds
        {
            get { return rectPanel; }
            set { rectPanel = value; }
        }

        /// <summary>
        /// K线柱的集合
        /// </summary>
        private List<CandleSeries> candleSeriesList = new List<CandleSeries>();

        public List<CandleSeries> CandleSeriesList
        {
            get { return candleSeriesList; }
            set { candleSeriesList = value; }
        }

        /// <summary>
        /// 柱状图的集合
        /// </summary>
        private List<HistogramSeries> historamSeriesList = new List<HistogramSeries>();

        public List<HistogramSeries> HistoramSeriesList
        {
            get { return historamSeriesList; }
            set { historamSeriesList = value; }
        }

        /// <summary>
        /// 线条的集合
        /// </summary>
        private List<TrendLineSeries> trendLineSeriesList = new List<TrendLineSeries>();

        public List<TrendLineSeries> TrendLineSeriesList
        {
            get { return trendLineSeriesList; }
            set { trendLineSeriesList = value; }
        }

        /// <summary>
        /// 计算Y轴所使用的字段
        /// </summary>
        private List<string> yScaleField = new List<string>();

        public List<string> YScaleField
        {
            get { return yScaleField; }
            set { yScaleField = value; }
        }

        /// <summary>
        /// 背景色刷
        /// </summary>
        private Brush bgBrush = new SolidBrush(Color.Black);

        public Brush BgBrush
        {
            get { return bgBrush; }
            set { bgBrush = value; }
        }

        /// <summary>
        /// X轴的线条画笔
        /// </summary>
        private Pen xScalePen = new Pen(Color.Red);

        public Pen XScalePen
        {
            get { return xScalePen; }
            set { xScalePen = value; }
        }

        /// <summary>
        /// 左侧Y轴的画笔
        /// </summary>
        private Pen leftScalePen = new Pen(Color.Red);

        public Pen LeftScalePen
        {
            get { return leftScalePen; }
            set { leftScalePen = value; }
        }

        /// <summary>
        /// 右侧Y轴的画笔
        /// </summary>
        private Pen rightScalePen = new Pen(Color.Red);

        public Pen RightScalePen
        {
            get { return rightScalePen; }
            set { rightScalePen = value; }
        }

        /// <summary>
        /// X轴提示框背景色的刷子
        /// </summary>
        private Brush xtip_Brush = new SolidBrush(Color.FromArgb(100, Color.Red));

        public Brush Xtip_Brush
        {
            get { return xtip_Brush; }
            set { xtip_Brush = value; }
        }

        /// <summary>
        /// X轴提示框文子色的画笔
        /// </summary>
        private Pen xTipFont_Pen = new Pen(Color.White);

        public Pen XTipFont_Pen
        {
            get { return xTipFont_Pen; }
            set { xTipFont_Pen = value; }
        }

        /// <summary>
        /// X轴提示框文字色的刷子
        /// </summary>
        private Brush xTipFont_Brush = new SolidBrush(Color.White);

        public Brush XTipFont_Brush
        {
            get { return xTipFont_Brush; }
            set { xTipFont_Brush = value; }
        }

        /// <summary>
        /// X轴提示框文字的字体
        /// </summary>
        private Font xTipFont = new Font("New Times Roman", 10, FontStyle.Bold);

        public Font XTipFont
        {
            get { return xTipFont; }
            set { xTipFont = value; }
        }

        /// <summary>
        /// 左侧Y轴提示框背景色的刷子
        /// </summary>
        /// </summary>
        private Brush leftyTip_Brush = new SolidBrush(Color.FromArgb(100, Color.Red));

        public Brush LeftyTip_Brush
        {
            get { return leftyTip_Brush; }
            set { leftyTip_Brush = value; }
        }

        /// <summary>
        /// 左侧Y轴提示框文字色的画笔
        /// </summary>
        private Pen leftTipFont_Pen = new Pen(Color.White);

        public Pen LeftTipFont_Pen
        {
            get { return leftTipFont_Pen; }
            set { leftTipFont_Pen = value; }
        }

        /// <summary>
        /// 左侧Y轴提示框文字色的刷子
        /// </summary>
        private Brush leftyTipFont_Brush = new SolidBrush(Color.White);

        public Brush LeftyTipFont_Brush
        {
            get { return leftyTipFont_Brush; }
            set { leftyTipFont_Brush = value; }
        }

        /// <summary>
        /// 左侧Y轴提示框文字的字体
        /// </summary>
        private Font leftyTipFont = new Font("New Times Roman", 10, FontStyle.Bold);

        public Font LeftyTipFont
        {
            get { return leftyTipFont; }
            set { leftyTipFont = value; }
        }

        /// <summary>
        /// 右侧Y轴提示框背景色的刷子
        /// </summary>
        /// </summary>
        private Brush rightyTip_Brush = new SolidBrush(Color.FromArgb(100, Color.Red));

        public Brush RightyTip_Brush
        {
            get { return rightyTip_Brush; }
            set { rightyTip_Brush = value; }
        }

        /// <summary>
        /// 右侧Y轴提示框文字色的刷子
        /// </summary>
        private Brush rightyTipFont_Brush = new SolidBrush(Color.White);

        public Brush RightyTipFont_Brush
        {
            get { return leftyTipFont_Brush; }
            set { leftyTipFont_Brush = value; }
        }

        /// <summary>
        /// 右侧Y轴提示框文字色的画笔
        /// </summary>
        private Pen rightyTipFont_Pen = new Pen(Color.White);

        public Pen RightyTipFont_Pen
        {
            get { return rightyTipFont_Pen; }
            set { rightyTipFont_Pen = value; }
        }

        /// <summary>
        /// 右侧Y轴提示框文字的字体
        /// </summary>
        private Font rightyTipFont = new Font("New Times Roman", 10, FontStyle.Bold);

        public Font RightyTipFont
        {
            get { return leftyTipFont; }
            set { leftyTipFont = value; }
        }

        /// <summary>
        /// 面板边线的画笔
        /// </summary>
        private Pen panelBorder_Pen = new Pen(Color.SkyBlue);

        public Pen BorderPen
        {
            get { return panelBorder_Pen; }
            set { panelBorder_Pen = value; }
        }

        /// <summary>
        /// 标题的笔刷
        /// </summary>
        private Brush titleFont_Brush = new SolidBrush(Color.White);

        public Brush TitleFont_Brush
        {
            get { return titleFont_Brush; }
            set { titleFont_Brush = value; }
        }

        /// <summary>
        /// 标题的字体
        /// </summary>
        private Font titleFont = new Font("New Times Roman", 9);

        public Font TitleFont
        {
            get { return titleFont; }
            set { titleFont = value; }
        }

        /// <summary>
        /// 网格线的画笔
        /// </summary>
        private Pen grid_Pen = new Pen(Color.FromArgb(100, Color.Red));

        public Pen Grid_Pen
        {
            get { return grid_Pen; }
            set { grid_Pen = value; }
        }

        /// <summary>
        /// X轴文字的刷子
        /// </summary>
        private Brush coordinateXFont_Brush = new SolidBrush(Color.White);

        public Brush CoordinateXFont_Brush
        {
            get { return coordinateXFont_Brush; }
            set { coordinateXFont_Brush = value; }
        }

        /// <summary>
        /// X轴文字的字体
        /// </summary>
        private Font coordinateXFont = new Font("New Times Roman", 9);

        public Font CoordinateXFont
        {
            get { return coordinateXFont; }
            set { coordinateXFont = value; }
        }

        /// <summary>
        /// 左侧Y轴文字的刷子
        /// </summary>
        private Brush leftYFont_Brush = new SolidBrush(Color.White);

        public Brush LeftYFont_Brush
        {
            get { return leftYFont_Brush; }
            set { leftYFont_Brush = value; }
        }

        /// <summary>
        /// 左侧Y轴文字的字体
        /// </summary>
        private Font leftYFont = new Font("New Times Roman", 9);

        public Font LeftYFont
        {
            get { return leftYFont; }
            set { leftYFont = value; }
        }

        /// <summary>
        /// 右侧Y轴文字的刷子
        /// </summary>
        private Brush rightYFont_Brush = new SolidBrush(Color.White);

        public Brush RightYFont_Brush
        {
            get { return rightYFont_Brush; }
            set { rightYFont_Brush = value; }
        }

        /// <summary>
        /// 右侧Y轴文字的字体
        /// </summary>
        private Font rightYFont = new Font("New Times Roman", 9);

        public Font RightYFont
        {
            get { return rightYFont; }
            set { rightYFont = value; }
        }

        /// <summary>
        /// 标题的高度
        /// </summary>
        private float titleHeight = 30;

        [Browsable(true)]
        public float TitleHeight
        {
            get { return titleHeight; }
            set { titleHeight = value; }
        }


        /// <summary>
        /// X轴的间隙
        /// </summary>
        private int scaleX_Height = 25;

        public int ScaleX_Height
        {
            get { return scaleX_Height; }
            set { scaleX_Height = value; }
        }
    }

    /// <summary>
    /// K线柱的属性
    /// </summary>
    public class CandleSeries
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public CandleSeries()
        {
        }

        /// <summary>
        /// 析构函数,释放对象
        /// </summary>
        ~CandleSeries()
        {
            if (this.upLine_Brush != null) upLine_Brush.Dispose();
            if (this.downLine_Brush != null) downLine_Brush.Dispose();
            if (this.middleLine_Pen != null) middleLine_Pen.Dispose();
            if (this.upLine_Pen != null) upLine_Pen.Dispose();
            if (this.upLine_TransparentBrush != null) upLine_TransparentBrush.Dispose();
            if (this.downLine_Pen != null) downLine_Pen.Dispose();
        }

        /// <summary>
        /// 买卖标识的字体
        /// </summary>
        private Font bsFont = new Font("宋体", 12, FontStyle.Bold);

        public Font BsFont
        {
            get { return bsFont; }
            set { bsFont = value; }
        }

        /// <summary>
        /// 买点标识色
        /// </summary>
        private Color buyColor = Color.Red;

        public Color BuyColor
        {
            get { return buyColor; }
            set { buyColor = value; }
        }

        /// <summary>
        /// 卖点标识色
        /// </summary>
        private Color sellColor = Color.SkyBlue;

        public Color SellColor
        {
            get { return sellColor; }
            set { sellColor = value; }
        }

        /// <summary>
        /// 买点的文字
        /// </summary>
        private string buyText = "B";

        public string BuyText
        {
            get { return buyText; }
            set { buyText = value; }
        }

        /// <summary>
        /// 卖点的文字
        /// </summary>
        private string sellText = "S";

        public string SellText
        {
            get { return sellText; }
            set { sellText = value; }
        }

        /// <summary>
        /// K线的名称
        /// </summary>
        private string candleName;

        public string CandleName
        {
            get { return candleName; }
            set { candleName = value; }
        }

        /// <summary>
        /// 买点对应的字段
        /// </summary>
        private string[] indBuySellField = new string[2];

        public string[] IndBuySellField
        {
            get { return indBuySellField; }
            set { indBuySellField = value; }
        }

        /// <summary>
        /// 最高价字段
        /// </summary>
        private string highField;

        public string HighField
        {
            get { return highField; }
            set { highField = value; }
        }

        /// <summary>
        /// 开盘价字段
        /// </summary>
        private string openField;

        public string OpenField
        {
            get { return openField; }
            set { openField = value; }
        }

        /// <summary>
        /// 收盘价字段
        /// </summary>
        private string closeField;

        public string CloseField
        {
            get { return closeField; }
            set { closeField = value; }
        }

        /// <summary>
        /// 最低价字段
        /// </summary>
        private string lowField;

        public string LowField
        {
            get { return lowField; }
            set { lowField = value; }
        }

        /// <summary>
        /// 是否被选中
        /// </summary>
        private bool hasSelect = false;

        public bool HasSelect
        {
            get { return hasSelect; }
            set { hasSelect = value; }
        }

        /// <summary>
        /// K线最大值对应的记录号
        /// </summary>
        private int maxRecord = 0;

        public int MaxRecord
        {
            get { return maxRecord; }
            set { maxRecord = value; }
        }

        /// <summary>
        ///  K线最小值对应的记录号
        /// </summary>
        private int minRecord = 0;

        public int MinRecord
        {
            get { return minRecord; }
            set { minRecord = value; }
        }

        /// <summary>
        /// 阳线刷
        /// </summary>
        private Brush upLine_Brush;

        public Brush UpLine_Brush
        {
            get { return upLine_Brush; }
            set { upLine_Brush = value; }
        }

        /// <summary>
        /// 阴线刷
        /// </summary>
        private Brush downLine_Brush;

        public Brush DownLine_Brush
        {
            get { return downLine_Brush; }
            set { downLine_Brush = value; }
        }

        /// <summary>
        /// 中线的画笔
        /// </summary>
        private Pen middleLine_Pen;

        public Pen MiddleLine_Pen
        {
            get { return middleLine_Pen; }
            set { middleLine_Pen = value; }
        }

        /// <summary>
        /// 阳线笔
        /// </summary>
        private Pen upLine_Pen;

        public Pen UpLinePen
        {
            get { return upLine_Pen; }
            set { upLine_Pen = value; }
        }

        /// <summary>
        /// 阴线笔
        /// </summary>
        private Pen downLine_Pen;

        public Pen DownLine_Pen
        {
            get { return downLine_Pen; }
            set { downLine_Pen = value; }
        }

        /// <summary>
        /// 阳线透明刷
        /// </summary>
        private Brush upLine_TransparentBrush;

        public Brush UpLineTransparentBrush
        {
            get { return upLine_TransparentBrush; }
            set { upLine_TransparentBrush = value; }
        }

        /// <summary>
        /// 阳线颜色
        /// </summary>
        private Color up_Color;

        public Color Up_Color
        {
            get { return up_Color; }
            set
            {
                up_Color = value;
                if (upLine_Brush != null)
                {
                    upLine_Brush.Dispose();
                }
                upLine_Brush = new SolidBrush(value);
                if (upLine_Pen != null)
                {
                    upLine_Pen.Dispose();
                }
                upLine_Pen = new Pen(value);
                if (upLine_TransparentBrush != null)
                {
                    upLine_TransparentBrush.Dispose();
                }
                upLine_TransparentBrush = new SolidBrush(Color.FromArgb(100, value));
            }
        }

        /// <summary>
        /// 中线的颜色
        /// </summary>
        private Color middle_Color = Color.White;

        public Color Middle_Color
        {
            get { return middle_Color; }
            set
            {
                middle_Color = value;
                if (middleLine_Pen != null)
                {
                    middleLine_Pen.Dispose();
                }
                middleLine_Pen = null;
                if (value != Color.Empty)
                {
                    middleLine_Pen = new Pen(value);
                }
            }
        }

        /// <summary>
        /// 阴线的颜色
        /// </summary>
        private Color down_Color;

        public Color Down_Color
        {
            get { return down_Color; }
            set
            {
                down_Color = value;
                if (downLine_Brush != null)
                {
                    downLine_Brush.Dispose();
                }
                downLine_Brush = new SolidBrush(value);
                if (downLine_Pen != null)
                {
                    downLine_Pen.Dispose();
                }
                downLine_Pen = new Pen(value);
            }
        }

        /// <summary>
        /// 开盘价的标题色
        /// </summary>
        private Color openTitleColor = Color.White;

        public Color OpenTitleColor
        {
            get { return openTitleColor; }
            set { openTitleColor = value; }
        }

        /// <summary>
        /// 最高价的标题色
        /// </summary>
        private Color highTitleColor = Color.Red;

        public Color HighTitleColor
        {
            get { return highTitleColor; }
            set { highTitleColor = value; }
        }

        /// <summary>
        /// 最低价的标题色
        /// </summary>
        private Color lowTitleColor = Color.Orange;

        public Color LowTitleColor
        {
            get { return lowTitleColor; }
            set { lowTitleColor = value; }
        }

        /// <summary>
        /// 收盘价的标题色
        /// </summary>
        private Color closeTitleColor = Color.Yellow;

        public Color CloseTitleColor
        {
            get { return closeTitleColor; }
            set { closeTitleColor = value; }
        }

        /// <summary>
        /// 是否在标题上显示字段
        /// </summary>
        private bool displayTitleField = true;

        public bool DisplayTitleField
        {
            get { return displayTitleField; }
            set { displayTitleField = value; }
        }
    }

    /// <summary>
    /// 柱状图的属性
    /// </summary>
    public class HistogramSeries
    {
        public HistogramSeries()
        {
        }

        /// <summary>
        /// 析构函数,释放对象
        /// </summary>
        ~HistogramSeries()
        {
            if (up_lineBrush != null)
            {
                up_lineBrush.Dispose();
            }
            if (down_lineBrush != null)
            {
                down_lineBrush.Dispose();
            }
            if (up_TransparentBrush != null)
            {
                up_TransparentBrush.Dispose();
            }
            if (up_Pen != null)
            {
                up_Pen.Dispose();
            }
            if (down_Pen != null)
            {
                down_Pen.Dispose();
            }
        }

        /// <summary>
        /// 是否被选中
        /// </summary>
        private bool hasSelect = false;

        public bool HasSelect
        {
            get { return hasSelect; }
            set { hasSelect = value; }
        }

        /// <summary>
        /// 字段名
        /// </summary>
        private string field;

        public string Field
        {
            get { return field; }
            set { field = value; }
        }

        /// <summary>
        /// 对应的K线名,设置后可以显示阴阳线
        /// </summary>
        private string relateCandleName;

        public string RelateCandleName
        {
            get { return relateCandleName; }
            set { relateCandleName = value; }
        }

        /// <summary>
        /// 透明的阳线画刷
        /// </summary>
        private Brush up_TransparentBrush;

        public Brush Up_TransparentBrush
        {
            get { return up_TransparentBrush; }
            set { up_TransparentBrush = value; }
        }

        /// <summary>
        /// 保存的阳线画笔
        /// </summary>
        private Pen up_Pen;

        public Pen Up_Pen
        {
            get { return up_Pen; }
            set { up_Pen = value; }
        }

        /// <summary>
        /// 保存的阴线画笔
        /// </summary>
        private Pen down_Pen;

        public Pen Down_Pen
        {
            get { return down_Pen; }
            set { down_Pen = value; }
        }

        /// <summary>
        /// 保存的阳线画刷
        /// </summary>
        private Brush up_lineBrush;

        public Brush Up_LineBrush
        {
            get { return up_lineBrush; }
            set { up_lineBrush = value; }
        }

        /// <summary>
        /// 保存的阴线画刷
        /// </summary>
        private Brush down_lineBrush;

        public Brush Down_lineBrush
        {
            get { return down_lineBrush; }
            set { down_lineBrush = value; }
        }

        /// <summary>
        /// 阳线的颜色
        /// </summary>
        private Color up_lineColor;

        public Color UpLineColor
        {
            get { return up_lineColor; }
            set
            {
                up_lineColor = value;
                if (up_lineBrush != null)
                {
                    up_lineBrush.Dispose();
                }
                up_lineBrush = new SolidBrush(value);
                if (up_TransparentBrush != null)
                {
                    up_TransparentBrush.Dispose();
                }
                up_TransparentBrush = new SolidBrush(Color.FromArgb(100, value));
                if (up_Pen != null)
                {
                    up_Pen.Dispose();
                }
                up_Pen = new Pen(value);
            }
        }

        /// <summary>
        /// 阴线的颜色
        /// </summary>
        private Color down_lineColor;

        public Color DownLineColor
        {
            get { return down_lineColor; }
            set
            {
                down_lineColor = value;
                if (down_lineBrush != null)
                {
                    down_lineBrush.Dispose();
                }
                Down_lineBrush = new SolidBrush(value);
                if (down_Pen != null)
                {
                    down_Pen.Dispose();
                }
                down_Pen = new Pen(value);
            }
        }

        /// <summary>
        /// 显示的标题名称
        /// </summary>
        private string displayName = string.Empty;

        public string DisplayName
        {
            get { return displayName; }
            set { displayName = value; }
        }

        /// <summary>
        /// 使用线的样式
        /// </summary>
        private bool lineStyle = false;

        public bool LineStyle
        {
            get { return lineStyle; }
            set { lineStyle = value; }
        }

        /// <summary>
        /// 线的宽度
        /// </summary>
        private int lineWidth = 1;

        public int LineWidth
        {
            get { return lineWidth; }
            set { lineWidth = value; }
        }
    }

    /// <summary>
    /// 线条的属性
    /// </summary>
    public class TrendLineSeries
    {
        public TrendLineSeries()
        {
        }

        /// <summary>
        /// 析构函数,释放对象
        /// </summary>
        ~TrendLineSeries()
        {
            if (this.up_linePen != null)
            {
                this.up_linePen.Dispose();
            }
            if (this.up_lineBrush != null)
            {
                this.up_lineBrush.Dispose();
            }
            if (this.transParentLineBrush != null)
            {
                this.transParentLineBrush.Dispose();
            }
            if (this.up_linePen != null)
            {
                this.up_linePen.Dispose();
            }
            if (this.down_lineBrush != null)
            {
                this.down_lineBrush.Dispose();
            }
        }

        /// <summary>
        /// 是否被选中
        /// </summary>
        private bool hasSelect = false;

        public bool HasSelect
        {
            get { return hasSelect; }
            set { hasSelect = value; }
        }

        /// <summary>
        /// 字段
        /// </summary>
        private string field = string.Empty;

        public string Field
        {
            get { return field; }
            set { field = value; }
        }

        /// <summary>
        /// 如果设置了该字段,则标题显示时使用该字段
        /// </summary>
        private string displayName = string.Empty;

        public string DisplayName
        {
            get { return displayName; }
            set { displayName = value; }
        }

        /// <summary>
        /// 保存的画笔
        /// </summary>
        private Pen up_linePen;

        public Pen UpLinePen
        {
            get { return up_linePen; }
            set { up_linePen = value; }
        }

        /// <summary>
        /// 保存的画刷
        /// </summary>
        private Brush up_lineBrush;

        public Brush Up_LineBrush
        {
            get { return up_lineBrush; }
            set { up_lineBrush = value; }
        }

        /// <summary>
        /// 线的颜色
        /// </summary>
        private Color up_lineColor;

        public Color UpLineColor
        {
            get { return up_lineColor; }
            set
            {
                up_lineColor = value;
                if (up_linePen != null)
                {
                    up_linePen.Dispose();
                }
                up_linePen = new Pen(value);
                if (up_lineBrush != null)
                {
                    up_lineBrush.Dispose();
                }
                up_lineBrush = new SolidBrush(value);
                if (transParentLineBrush != null)
                {
                    transParentLineBrush.Dispose();
                }
                transParentLineBrush = new SolidBrush(Color.FromArgb(100, value));
            }
        }

        /// <summary>
        /// 阴线的画笔
        /// </summary>
        private Pen down_linePen = new Pen(Color.Yellow);

        public Pen DownLinePen
        {
            get { return down_linePen; }
            set { down_linePen = value; }
        }

        /// <summary>
        /// 阴线的笔刷
        /// </summary>
        private Brush down_lineBrush;

        public Brush Down_lineBrush
        {
            get { return down_lineBrush; }
            set { down_lineBrush = value; }
        }

        /// <summary>
        /// 阴线的颜色
        /// </summary>
        private Color down_LineColor;

        public Color DownLineColor
        {
            get { return down_LineColor; }
            set
            {
                down_LineColor = value;
                if (down_linePen != null)
                {
                    down_linePen.Dispose();
                }
                down_linePen = new Pen(value);
                if (down_lineBrush != null)
                {
                    down_lineBrush.Dispose();
                }
                down_lineBrush = new SolidBrush(value);
            }
        }

        /// <summary>
        /// 透明色画刷
        /// </summary>
        private Brush transParentLineBrush;

        public Brush TransParentLineBrush
        {
            get { return transParentLineBrush; }
            set { transParentLineBrush = value; }
        }
    }

    /// <summary>
    /// 标记的属性
    /// </summary>
    public class SignalSeries
    {
        public SignalSeries(double value, SignalType st, Color stColor, bool canDrag)
        {
            this.value = value;
            this.signal = st;
            this.signalColor = stColor;
            this.canDrag = canDrag;
        }

        /// <summary>
        /// 标记的类型
        /// </summary>
        private SignalType signal = SignalType.UpArrow;

        public SignalType Signal
        {
            get { return signal; }
            set { signal = value; }
        }

        /// <summary>
        /// 标记的值
        /// </summary>
        private double value;

        public double Value
        {
            get { return this.value; }
            set { this.value = value; }
        }

        private bool canDrag = false;

        public bool CanDrag
        {
            get { return canDrag; }
            set { canDrag = value; }
        }

        /// <summary>
        /// 标记的颜色
        /// </summary>
        private Color signalColor = Color.Red;

        public Color SignalColor
        {
            get { return signalColor; }
            set { signalColor = value; }
        }

        /// <summary>
        /// 根据类型获取GraphicsPath.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public GraphicsPath GetGPByType(float x, float y, int width)
        {
            if (width > 10)
            {
                width = 14;
            }
            GraphicsPath gp = new GraphicsPath();
            switch (signal)
            {
                case SignalType.UpArrow:
                    gp.AddLine(x, y, x + width / 2, y + width);
                    gp.AddLine(x + width / 2, y + width, x + width / 4, y + width);
                    gp.AddLine(x + width / 4, y + width, x + width / 4, y + width * 3 / 2);
                    gp.AddLine(x + width / 4, y + width * 3 / 2, x - width / 4, y + width * 3 / 2);
                    gp.AddLine(x - width / 4, y + width * 3 / 2, x - width / 4, y + width);
                    gp.AddLine(x - width / 4, y + width, x - width / 2, y + width);
                    gp.AddLine(x - width / 2, y + width, x, y);
                    gp.CloseFigure();
                    break;
                case SignalType.DownArrow:
                    gp.AddLine(x, y, x + width / 2, y - width);
                    gp.AddLine(x + width / 2, y - width, x + width / 4, y - width);
                    gp.AddLine(x + width / 4, y - width, x + width / 4, y - width * 3 / 2);
                    gp.AddLine(x + width / 4, y - width * 3 / 2, x - width / 4, y - width * 3 / 2);
                    gp.AddLine(x - width / 4, y - width * 3 / 2, x - width / 4, y - width);
                    gp.AddLine(x - width / 4, y - width, x - width / 2, y - width);
                    gp.AddLine(x - width / 2, y - width, x, y);
                    gp.CloseFigure();
                    break;
                case SignalType.UpArrowWithOutTail:
                    gp.AddLine(x, y, x + width / 2, y + width);
                    gp.AddLine(x + width / 2, y + width, x - width / 2, y + width);
                    gp.AddLine(x - width / 2, y + width, x, y);
                    gp.CloseFigure();
                    break;
                case SignalType.DownArrowWithOutTail:
                    gp.AddLine(x, y, x + width / 2, y - width);
                    gp.AddLine(x + width / 2, y - width, x - width / 2, y - width);
                    gp.AddLine(x - width / 2, y - width, x, y);
                    gp.CloseFigure();
                    break;
                case SignalType.LeftArrow:
                    gp.AddLine(x + width / 2, y, x - width / 2, y - width / 2);
                    gp.AddLine(x - width / 2, y - width / 2, x - width / 2, y + width / 2);
                    gp.AddLine(x - width / 2, y + width / 2, x + width / 2, y);
                    gp.CloseFigure();
                    break;
                case SignalType.RightArrow:
                    gp.AddLine(x - width / 2, y, x + width / 2, y - width / 2);
                    gp.AddLine(x + width / 2, y - width / 2, x + width / 2, y + width / 2);
                    gp.AddLine(x + width / 2, y + width / 2, x - width / 2, y);
                    gp.CloseFigure();
                    break;
            }
            return gp;
        }
    }

    /// <summary>
    /// 平滑移动平均线(SMA)
    /// </summary>
    public class IndicatorSimpleMovingAverage
    {
        public IndicatorSimpleMovingAverage()
        {

        }

        /// <summary>
        /// 目标字段
        /// </summary>
        private string target = string.Empty;

        public string Target
        {
            get { return target; }
            set { target = value; }
        }

        /// <summary>
        /// 周期
        /// </summary>
        private int cycle = 5;

        public int Cycle
        {
            get { return cycle; }
            set { cycle = value; }
        }

        /// <summary>
        /// 趋势线对象
        /// </summary>
        private TrendLineSeries trendLineSeries = null;

        public TrendLineSeries TrendLineSeries
        {
            get { return trendLineSeries; }
            set { trendLineSeries = value; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        private DataTable dataSource;

        public DataTable DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        /// <summary>
        /// 计算简单移动平均线的值
        /// </summary>
        /// <param name="field"></param>
        /// <param name="n"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public double Calculate(int r)
        {
            if (dataSource.Columns.Contains(trendLineSeries.Field) && dataSource.Columns.Contains(target))
            {
                DataRow dr = dataSource.Rows[r];
                double curValue = Convert.ToDouble(dataSource.Rows[r][target]);
                return CommonClass.CalcuteSimpleMovingAvg(r, cycle, trendLineSeries.Field, target, curValue, dataSource);
            }
            return double.MinValue;
        }
    }

    /// <summary>
    /// 指数移动平均线(EMA)
    /// </summary>
    public class IndicatorExponentialMovingAverage
    {
        public IndicatorExponentialMovingAverage()
        {

        }

        /// <summary>
        /// 目标字段
        /// </summary>
        private string target = string.Empty;

        public string Target
        {
            get { return target; }
            set { target = value; }
        }

        /// <summary>
        /// 周期
        /// </summary>
        private int cycle = 5;

        public int Cycle
        {
            get { return cycle; }
            set { cycle = value; }
        }

        /// <summary>
        /// 趋势线对象
        /// </summary>
        private TrendLineSeries trendLineSeries = null;

        public TrendLineSeries TrendLineSeries
        {
            get { return trendLineSeries; }
            set { trendLineSeries = value; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        private DataTable dataSource;

        public DataTable DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        /// <summary>
        /// 计算指数平均数指标的值
        /// </summary>
        /// <param name="field"></param>
        /// <param name="target"></param>
        /// <param name="n"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public double Calculate(int r)
        {
            return CommonClass.CalculateExponentialMovingAvg(trendLineSeries.Field, target, cycle, dataSource, r);
        }
    }

    /// <summary>
    /// 随机指标(KDJ)
    /// </summary>
    public class IndicatorStochasticOscillator
    {
        public IndicatorStochasticOscillator()
        {
        }

        /// <summary>
        /// K值趋势线
        /// </summary>
        private TrendLineSeries tlsK = null;

        public TrendLineSeries TlsK
        {
            get { return tlsK; }
            set { tlsK = value; }
        }

        /// <summary>
        /// D值趋势线
        /// </summary>
        private TrendLineSeries tlsD = null;

        public TrendLineSeries TlsD
        {
            get { return tlsD; }
            set { tlsD = value; }
        }

        /// <summary>
        /// J值趋势线
        /// </summary>
        private TrendLineSeries tlsJ = null;

        public TrendLineSeries TlsJ
        {
            get { return tlsJ; }
            set { tlsJ = value; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        private DataTable dataSource;

        public DataTable DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        /// <summary>
        /// K值周期
        /// </summary>
        private int kPeriods = 9;

        public int KPeriods
        {
            get { return kPeriods; }
            set { kPeriods = value; }
        }

        /// <summary>
        /// 慢速K值周期
        /// </summary>
        private int kSlowing = 3;

        public int KSlowing
        {
            get { return kSlowing; }
            set { kSlowing = value; }
        }

        /// <summary>
        /// D值周期
        /// </summary>
        private int dPeriods = 9;

        public int DPeriods
        {
            get { return dPeriods; }
            set { dPeriods = value; }
        }

        /// <summary>
        /// 收盘价字段
        /// </summary>
        private string close = string.Empty;

        public string Close
        {
            get { return close; }
            set { close = value; }
        }

        /// <summary>
        /// 最高价字段
        /// </summary>
        private string high = string.Empty;

        public string High
        {
            get { return high; }
            set { high = value; }
        }

        /// <summary>
        /// 最低价字段
        /// </summary>
        private string low = string.Empty;

        public string Low
        {
            get { return low; }
            set { low = value; }
        }

        /// <summary>
        /// 获取指定索引的K,D,J的值
        /// K=昨日K*2/3+RSV/3;
        /// D=昨日D*2/3+K/3;
        /// J=3*K-2*D
        /// </summary>
        /// <param name="panelID"></param>
        /// <returns></returns>
        public double[] Calculate(int r)
        {
            double k = 100;
            double d = 100;
            if (r > 0)
            {
                double lastK = Convert.ToDouble(dataSource.Rows[r - 1][tlsK.Field]);
                double lastD = Convert.ToDouble(dataSource.Rows[r - 1][tlsD.Field]);
                k = lastK * 2 / 3 + RSV(r) / 3;
                d = lastD * 2 / 3 + k / 3;
            }
            double j = 3 * k - 2 * d;
            return new double[] { k, d, j };
        }

        /// <summary>
        /// 获取未成熟随机指标值
        /// </summary>
        /// <param name="interval"></param>
        /// <param name="rowIndex"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public double RSV(int r)
        {
            int endIndex = r - (kPeriods - 1);
            if (endIndex < 0)
            {
                endIndex = 0;
            }
            double currentClose = Convert.ToDouble(dataSource.Rows[r][close]);
            List<double> highList = new List<double>();
            List<double> lowList = new List<double>();
            for (int i = r; i >= endIndex; i--)
            {
                double h = Convert.ToDouble(dataSource.Rows[i][high]);
                double l = Convert.ToDouble(dataSource.Rows[i][low]);
                highList.Add(h);
                lowList.Add(l);
            }
            double nHigh = CommonClass.GetHighValue(highList);
            double nLow = CommonClass.GetLowValue(lowList);
            return (currentClose - nLow) / (nHigh - nLow) * 100;
        }
    }

    /// <summary>
    /// 指数平滑异同移动平均线(MACD)
    /// </summary>
    public class IndicatorMACD
    {
        public IndicatorMACD()
        {

        }

        /// <summary>
        /// MACD柱状图
        /// </summary>
        private HistogramSeries hsMACD = null;

        public HistogramSeries HsMACD
        {
            get { return hsMACD; }
            set { hsMACD = value; }
        }

        /// <summary>
        /// Diff线
        /// </summary>
        private TrendLineSeries tlsDiff = null;

        public TrendLineSeries TlsDiff
        {
            get { return tlsDiff; }
            set { tlsDiff = value; }
        }

        /// <summary>
        /// Dea线
        /// </summary>
        private TrendLineSeries tlsDea = null;

        public TrendLineSeries TlsDea
        {
            get { return tlsDea; }
            set { tlsDea = value; }
        }

        /// <summary>
        /// 长周期
        /// </summary>
        private int longCycle = 26;

        public int LongCycle
        {
            get { return longCycle; }
            set { longCycle = value; }
        }

        /// <summary>
        /// 短周期
        /// </summary>
        private int shortCycle = 12;

        public int ShortCycle
        {
            get { return shortCycle; }
            set { shortCycle = value; }
        }

        /// <summary>
        /// 标记周期
        /// </summary>
        private int signalPeriods = 9;

        public int SignalPeriods
        {
            get { return signalPeriods; }
            set { signalPeriods = value; }
        }

        /// <summary>
        /// 收盘价字段
        /// </summary>
        private string close = string.Empty;

        public string Close
        {
            get { return close; }
            set { close = value; }
        }

        /// <summary>
        /// 长周期EMA字段
        /// </summary>
        private string longCycleEMA = CommonClass.GetGuid();

        public string LongCycleEMA
        {
            get { return longCycleEMA; }
            set { longCycleEMA = value; }
        }

        /// <summary>
        /// 短周期EMA字段
        /// </summary>
        private string shortCycleEMA = CommonClass.GetGuid();

        public string ShortCycleEMA
        {
            get { return shortCycleEMA; }
            set { shortCycleEMA = value; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        private DataTable dataSource = null;

        public DataTable DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        /// <summary>
        /// 根据指定索引的MACD,DIFF,DEA的值
        /// DIFF=EMA(C,ShortCycle)-EMA(C,LongCycle);
        /// DEA=DIFF*0.2-昨日DEA*0.8
        /// MACD=2*(DIFF-DEA)
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        public double[] Calulate(int r)
        {
            double macd = 0;
            double diff = 0;
            double dea = 0;
            if (r > 1)
            {
                DataRow dr = dataSource.Rows[r];
                double longEMA = Convert.ToDouble(dr[longCycleEMA]);
                double shortEMA = Convert.ToDouble(dr[shortCycleEMA]);
                diff = shortEMA - longEMA;
                double lastDea = Convert.ToDouble(dataSource.Rows[r - 1][tlsDea.Field]);
                dea = diff * 0.2 + lastDea * 0.8;
                macd = 2 * (diff - dea);
            }
            return new double[] { macd, diff, dea };
        }
    }

    /// <summary>
    /// 布林带
    /// </summary>
    public class IndicatorBollingerBands
    {
        public IndicatorBollingerBands()
        {

        }

        /// <summary>
        /// 中间的布林线
        /// </summary>
        private TrendLineSeries tlsM = null;

        public TrendLineSeries TlsM
        {
            get { return tlsM; }
            set { tlsM = value; }
        }

        /// <summary>
        /// 上边的布林线
        /// </summary>
        private TrendLineSeries tlsU = null;

        public TrendLineSeries TlsU
        {
            get { return tlsU; }
            set { tlsU = value; }
        }

        /// <summary>
        /// 下边的布林线
        /// </summary>
        private TrendLineSeries tlsD = null;

        public TrendLineSeries TlsD
        {
            get { return tlsD; }
            set { tlsD = value; }
        }

        /// <summary>
        /// 收盘价字段
        /// </summary>
        private string close = string.Empty;

        public string Close
        {
            get { return close; }
            set { close = value; }
        }

        /// <summary>
        /// 周期
        /// </summary>
        private int periods = 20;

        public int Periods
        {
            get { return periods; }
            set { periods = value; }
        }

        /// <summary>
        /// 标准差
        /// </summary>
        private int standardDeviations = 2;

        public int StandardDeviations
        {
            get { return standardDeviations; }
            set { standardDeviations = value; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        private DataTable dataSource = null;

        public DataTable DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        /// <summary>
        /// 计算指定索引的MID,DOWN,UP值
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        public double[] Calculate(int r)
        {
            double closeValue = Convert.ToDouble(dataSource.Rows[r][this.Close]);
            double mid = CommonClass.CalcuteSimpleMovingAvg(r, periods, TlsM.Field, close, closeValue, dataSource);
            if (mid == double.MinValue)
            {
                mid = 0;
            }
            double md = 0;
            if (r >= periods - 1)
            {
                double sumValue = (closeValue - mid) * (closeValue - mid);
                for (int i = r - 1; i >= r - (periods - 1); i--)
                {
                    double curClose = Convert.ToDouble(dataSource.Rows[i][this.Close]);
                    double curMA = Convert.ToDouble(dataSource.Rows[i][this.tlsM.Field]);
                    sumValue += (curClose - curMA) * (curClose - curMA);
                }
                md = standardDeviations * Math.Sqrt(sumValue / periods);
            }
            double up = mid + 2 * md;
            double down = mid - 2 * md;
            return new double[] { mid, up, down };
        }
    }

    /// <summary>
    /// 标题字段的属性
    /// </summary>
    public class TitleField
    {
        public TitleField(string relateSeriesField, string field,
            string displayTitle, Color fieldColor, bool onlyShow)
        {
            this.relateSeriesField = relateSeriesField;
            this.field = field;
            this.displayTitle = displayTitle;
            this.FieldColor = fieldColor;
            this.mainFlag = onlyShow;
        }

        ~TitleField()
        {
            if (fieldBrush != null) fieldBrush.Dispose();
        }

        /// <summary>
        /// 相关的线条字段的名称
        /// </summary>
        private string relateSeriesField = string.Empty;

        public string RelateSeriesField
        {
            get { return relateSeriesField; }
            set { relateSeriesField = value; }
        }

        /// <summary>
        /// 字段名
        /// </summary>
        private string field = string.Empty;

        public string Field
        {
            get { return field; }
            set { field = value; }
        }

        /// <summary>
        /// 显示的名称
        /// </summary>
        private string displayTitle = string.Empty;

        public string DisplayTitle
        {
            get { return displayTitle; }
            set { displayTitle = value; }
        }

        /// <summary>
        /// 字段的颜色
        /// </summary>
        private Color fieldColor = Color.White;

        public Color FieldColor
        {
            get { return fieldColor; }
            set
            {
                fieldColor = value;
                if (fieldBrush != null)
                {
                    fieldBrush.Dispose();
                }
                fieldBrush = new SolidBrush(value);
            }
        }

        /// <summary>
        /// 字段颜色的刷子
        /// </summary>
        private Brush fieldBrush = new SolidBrush(Color.White);

        public Brush FieldBrush
        {
            get { return fieldBrush; }
            set { fieldBrush = value; }
        }

        /// <summary>
        /// 主标题flag
        /// </summary>
        private bool mainFlag = false;

        public bool MainFlag
        {
            get { return mainFlag; }
            set { mainFlag = value; }
        }
    }

    /// <summary>
    /// 标记的类型
    /// </summary>
    public enum SignalType
    {
        UpArrow,
        DownArrow,
        UpArrowWithOutTail,
        DownArrowWithOutTail,
        LeftArrow,
        RightArrow
    }

    /// <summary>
    /// 周期类型
    /// </summary>
    public enum IntervalType
    {
        Second,
        Minute,
        Day,
        Week,
        Month,
        Year
    }

    /// <summary>
    /// 指标的类型
    /// </summary>
    public enum IndicatorType
    {
        SimpleMovingAverage,
        ExponentialMovingAverage,
        StochasticOscillator
    }
}
